package il.ac.technion.cs236700.utils.composite;

import java.util.Comparator;
import java.util.List;

import il.ac.technion.cs236700.utils.visitor.Action;

/** 
 * An implementation for the Composite Design Pattern - the Component part
 * 
 * @authors Regev Azriel & Sharon Ronen
 *
 */
public abstract class Component<T> {

	protected T data;
	protected Component<T> parent;
	
	public Component(T data){
		this.data = data;
	}
	
	public Component(T data,Component<T> parent){
		this.data = data;
		this.parent = parent;
	}
	
	public abstract void add(Component<T> c);
	public abstract boolean remove(Component<T> c);
	public abstract Component<T> getChild(int index);
	public abstract List<Component<T>> getChildren();
	public abstract void visit(Action<T> action);
	public abstract Component<T> search(Comparator<T> c,T arg);
	public Component<T> getParent(){ return parent; }
	public void setParent(Component<T> parent){ this.parent = parent; }
	public T getData(){ return data; }
	
	@Override
	public String toString() {
		return data.toString();
	}
	
	@Override
	public boolean equals(Object obj) {		
		if (!(obj instanceof Component)) return false;
		return data.equals(((Component<?>)obj).data) && 
		((parent == null &&((Component<?>)obj).parent == null) 
				|| parent.equals(((Component<?>)obj).parent));
	}
	
	@Override
	public int hashCode() {
		return data.hashCode();
	}
	
}
